package com.bbcare.img.plat.service.impl;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.bbcare.comm.*;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.shiro.util.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.bbcare.img.plat.entity.AiEquip;
import com.bbcare.img.plat.entity.AiEquipClassInfo;
import com.bbcare.img.plat.entity.AiProgram;
import com.bbcare.img.plat.service.IEquipManageService;
import com.bbcare.img.plat.store.ibatis.IEquipClassDAO;
import com.bbcare.img.plat.store.ibatis.IEquipDAO;
import com.bbcare.img.plat.store.ibatis.IIaOperationRecordDAO;
import com.bbcare.img.plat.store.ibatis.IProgramDAO;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

/**
 * @name: 设备管理服务接口实现
 * @author: DemonLee
 * @createTime: 2017.10.26
 * @description: 设备管理相关操作，包括增加，修改及查询等
 * @modify:
 *
 */
@Service
public class EquipManageServiceImpl implements IEquipManageService {
	private final Log logger = LogFactory.getLog(EquipManageServiceImpl.class);

	@Autowired
	private IEquipClassDAO equipClassDao;

	@Autowired
	private IEquipDAO equipDao;

	@Autowired
	private IProgramDAO programDao;

	@Autowired
	private IIaOperationRecordDAO iaOperationRecordDao;

	@Autowired
	private JedisPool pool;

	// 设备分类查询接口实现
	public List<Object> listEquipClass(Map<String, Object> argMap) throws Exception {
		List<Object> outList = new ArrayList<Object>();
		Map<String, Object> sessionInfo = ToolUtil.typeCast(argMap.get("sessionInfo"));
		String tenantId = (String) sessionInfo.get("tenantId");

		Map<String, Object> qryMapIn = new HashMap<String, Object>();
		qryMapIn.put("tenantId", tenantId);
		qryMapIn.put("status", Constants.TABLE_RECORD_STATUS_NOMAL);
		outList = ToolUtil.typeCast(equipClassDao.listEquipClassDict(qryMapIn));

		return outList;
	}

	// 新增设备接口实现
	@Transactional
	public Map<String, Object> saveNewEquip(Map<String, Object> mapIn) throws Exception {
		logger.debug("mapIn==" + mapIn);
		Map<String, Object> argMap = new HashMap<String, Object>(mapIn);
		Map<String, Object> outMap = new HashMap<String, Object>();
		Map<String, Object> sessionInfo = ToolUtil.typeCast(argMap.get("sessionInfo"));
		Map<String, Object> oprInfo = ToolUtil.typeCast(argMap.get("oprInfo"));
		Map<String, Object> equipInfo = ToolUtil.typeCast(argMap.get("equipInfo"));
		String tenantId = (String) sessionInfo.get("tenantId");
		String authorId = (String) sessionInfo.get("authorId");
		String equipAlias = (String) equipInfo.get("equipAlias");
		String classId = (String) equipInfo.get("classId");
		String programId = (String) equipInfo.get("programId");
		String updateTime = (String) oprInfo.get("updateTime");
		String updateAccept = (String) oprInfo.get("updateAccept");

		// 查询是否已有相同设备编号的设备
		Map<String, Object> qryMapIn = new HashMap<String, Object>();
		qryMapIn.put("tenantId", tenantId);
		qryMapIn.put("equipAlias", equipAlias);
		qryMapIn.put("classId", classId);
		List<AiEquip> equipList = equipDao.listEquipByUnique(qryMapIn);
		if (!CollectionUtils.isEmpty(equipList)) {
			throw (new AppException(ErrorCode.IMG_EXCEPTION_EQUIP_HAS_ALREADY_EXISTS,
					"该设备【" + equipAlias + "】已存在，请勿重复添加！"));
		}
		// 校验小程序是否有效
		qryMapIn.clear();
		qryMapIn.put("id", programId);
		List<AiProgram> pgList = programDao.listProgramByCondition(qryMapIn);
		if (CollectionUtils.isEmpty(pgList)) {
			throw (new AppException(ErrorCode.IMG_EXCEPTION_PROGRAM_NOT_EXISTS, "该程序编号对应注册信息不存在，添加失败！"));
		} else {
			AiProgram pgVo = pgList.get(0);
			String pgStatus = pgVo.getStatus();
			if (null == pgStatus) {
				pgStatus = "";
			}
			if (Constants.TABLE_RECORD_STATUS_INVALID.equals(pgStatus)) {
				throw (new AppException(ErrorCode.IMG_EXCEPTION_PROGRAM_IS_INVALID, "该程序编号对应注册信息已失效，添加失败！"));
			}
		}
		// 再校验programId下是否已绑定其他设备
		qryMapIn.clear();
		qryMapIn.put("programId", programId);
		equipList = equipDao.listEquipByProgramId(qryMapIn);
		if (!CollectionUtils.isEmpty(equipList)) {
			throw (new AppException(ErrorCode.IMG_EXCEPTION_EQUIP_PROGRAMID_HAS_ALREADY_BINDING,
					"该程序编号【" + programId + "】已绑定其他设备，添加失败！"));
		}

		// 插入新设备
		String equipId = SeqUtil.getSeqNo(Constants.SEQ_NO_FOR_IMG_EQUIP_ID);
		AiEquip equipVo = new AiEquip();
		equipVo.setClassId(classId);
		equipVo.setCreateAuthor(authorId);
		equipVo.setCreateTime(updateTime);
		equipVo.setEquipAlias(equipAlias);
		equipVo.setEquipCode((String) equipInfo.get("equipCode"));
		equipVo.setEquipDesc((String) equipInfo.get("equipDesc"));
		equipVo.setEquipName((String) equipInfo.get("equipName"));
		equipVo.setId(equipId);
		equipVo.setModelNumber((String) equipInfo.get("modelNumber"));
		equipVo.setProgramId(programId);
		equipVo.setStatus(Constants.TABLE_RECORD_STATUS_NOMAL);
		equipVo.setTenantId(tenantId);
		equipVo.setUpdateAuthor(authorId);
		equipVo.setUpdateTime(updateTime);
		equipDao.saveAiEquip(equipVo);

		// 查询当前租户下是否需要新增设备类型
		qryMapIn.clear();
		qryMapIn.put("tenantId", tenantId);
		qryMapIn.put("classId", classId);
		List<AiEquipClassInfo> eciList = equipClassDao.listEquipClassInfo(qryMapIn);
		if (CollectionUtils.isEmpty(eciList)) {
			// 在当前租户下插入新的设备类型
			AiEquipClassInfo eciVo = new AiEquipClassInfo();
			eciVo.setClassId(classId);
			eciVo.setCreateAuthor(authorId);
			eciVo.setCreateTime(updateTime);
			eciVo.setId(SeqUtil.getSeqNo(Constants.SEQ_NO_FOR_IMG_EQUIPCLASS_ASSOCI_ID));
			eciVo.setStatus(Constants.TABLE_RECORD_STATUS_NOMAL);
			eciVo.setTenantId(tenantId);
			eciVo.setUpdateAuthor(authorId);
			eciVo.setUpdateTime(updateTime);
			equipClassDao.saveAiEquipClassInfo(eciVo);
		}

		// 操作记录
		Map<String, Object> paramRecord = new HashMap<String, Object>();
		Calendar now = Calendar.getInstance();
		paramRecord.put("month", String.valueOf(now.get(Calendar.MONTH) + 1));
		paramRecord.put("day", String.valueOf(now.get(Calendar.DAY_OF_MONTH)));
		paramRecord.put("userId", "");
		paramRecord.put("queueId", "");
		paramRecord.put("opUser", authorId);
		paramRecord.put("opTime", updateTime);
		paramRecord.put("remark", oprInfo.get("opNote"));
		paramRecord.put("busiCategory", Constants.DOCTOR_ACTIVE_BUSI_TYPE_10);
		paramRecord.put("opUsertype", Constants.OPCODE_TYPE_DOCTOR);
		paramRecord.put("id", updateAccept);
		paramRecord.put("opDesc", oprInfo.get("opNote"));
		paramRecord.put("opCode", oprInfo.get("opCode"));
		paramRecord.put("busiId", null);
		paramRecord.put("tenantId", tenantId);
		paramRecord.put("opType", oprInfo.get("opType"));
		paramRecord.put("taskId", "");
		paramRecord.put("breifIntro", null);
		iaOperationRecordDao.saveOperationRecord(paramRecord);

		outMap.put("equipId", equipId);
		return outMap;
	}

	// 设备信息修改接口实现
	@Transactional
	public Map<String, Object> updateEquipInfo(Map<String, Object> mapIn) throws Exception {
		Map<String, Object> argMap = new HashMap<String, Object>(mapIn);
		Map<String, Object> outMap = new HashMap<String, Object>();
		Map<String, Object> sessionInfo = ToolUtil.typeCast(argMap.get("sessionInfo"));
		Map<String, Object> oprInfo = ToolUtil.typeCast(argMap.get("oprInfo"));
		Map<String, Object> equipInfo = ToolUtil.typeCast(argMap.get("equipInfo"));
		String tenantId = (String) sessionInfo.get("tenantId");
		String authorId = (String) sessionInfo.get("authorId");
		String equipAlias = (String) equipInfo.get("equipAlias");
		String classId = (String) equipInfo.get("classId");
		String programId = (String) equipInfo.get("programId");
		String equipId = (String) equipInfo.get("equipId");
		String updateTime = (String) oprInfo.get("updateTime");
		String updateAccept = (String) oprInfo.get("updateAccept");

		// 根据设备id查询设备信息
		Map<String, Object> qryMapIn = new HashMap<String, Object>();
		qryMapIn.put("id", equipId);
		List<AiEquip> equipList = equipDao.listEquipByCondition(qryMapIn);
		if (CollectionUtils.isEmpty(equipList)) {
			throw (new AppException(ErrorCode.IMG_EXCEPTION_EQUIP_HAS_ALREADY_EXISTS, "根据设备id未查询到对应设备信息，修改失败！"));
		}
		// 除了当前设备，查询是否已有相同设备编号的设备
		qryMapIn.clear();
		qryMapIn.put("tenantId", tenantId);
		qryMapIn.put("equipAlias", equipAlias);
		qryMapIn.put("classId", classId);
		qryMapIn.put("idRev", equipId);
		equipList = equipDao.listEquipByCondition(qryMapIn);
		if (!CollectionUtils.isEmpty(equipList)) {
			throw (new AppException(ErrorCode.IMG_EXCEPTION_EQUIP_HAS_ALREADY_EXISTS,
					"该设备【" + equipAlias + "】已存在，修改失败！"));
		}
		// 校验小程序是否有效
		qryMapIn.clear();
		qryMapIn.put("id", programId);
		List<AiProgram> pgList = programDao.listProgramByCondition(qryMapIn);
		if (CollectionUtils.isEmpty(pgList)) {
			throw (new AppException(ErrorCode.IMG_EXCEPTION_PROGRAM_NOT_EXISTS, "该程序编号对应注册信息不存在，添加失败！"));
		} else {
			AiProgram pgVo = pgList.get(0);
			String pgStatus = pgVo.getStatus();
			if (null == pgStatus) {
				pgStatus = "";
			}
			if (Constants.TABLE_RECORD_STATUS_INVALID.equals(pgStatus)) {
				throw (new AppException(ErrorCode.IMG_EXCEPTION_PROGRAM_IS_INVALID, "该程序编号对应注册信息已失效，添加失败！"));
			}
		}
		// 除了当前设备，再校验programId下是否已绑定其他设备
		qryMapIn.clear();
		qryMapIn.put("programId", programId);
		qryMapIn.put("idRev", equipId);
		equipList = equipDao.listEquipByCondition(qryMapIn);
		if (!CollectionUtils.isEmpty(equipList)) {
			throw (new AppException(ErrorCode.IMG_EXCEPTION_EQUIP_PROGRAMID_HAS_ALREADY_BINDING,
					"该程序编号【" + programId + "】已绑定其他设备，修改失败！"));
		}

		// 修改设备信息
		Map<String, Object> upMapIn = new HashMap<String, Object>();
		upMapIn.put("id", equipId);
		upMapIn.put("updateTime", updateTime);
		upMapIn.put("updateAuthor", authorId);
		upMapIn.put("equipName", (String) equipInfo.get("equipName"));
		upMapIn.put("equipCode", (String) equipInfo.get("equipCode"));
		upMapIn.put("modelNumber", (String) equipInfo.get("modelNumber"));
		upMapIn.put("equipDesc", (String) equipInfo.get("equipDesc"));
		upMapIn.put("programId", programId);
		upMapIn.put("equipAlias", equipAlias);
		upMapIn.put("classId", classId);
		int iu = equipDao.updateAiEquip(upMapIn);
		if (0 == iu) {
			throw (new AppException(ErrorCode.IMG_EXCEPTION_EQUIP_NOT_EXISTS, "根据设备id未查询到对应设备信息，修改失败！"));
		}

		// 查询当前租户下是否需要新增设备类型
		qryMapIn.clear();
		qryMapIn.put("tenantId", tenantId);
		qryMapIn.put("classId", classId);
		List<AiEquipClassInfo> eciList = equipClassDao.listEquipClassInfo(qryMapIn);
		if (CollectionUtils.isEmpty(eciList)) {
			// 在当前租户下插入新的设备类型
			AiEquipClassInfo eciVo = new AiEquipClassInfo();
			eciVo.setClassId(classId);
			eciVo.setCreateAuthor(authorId);
			eciVo.setCreateTime(updateTime);
			eciVo.setId(SeqUtil.getSeqNo(Constants.SEQ_NO_FOR_IMG_EQUIPCLASS_ASSOCI_ID));
			eciVo.setStatus(Constants.TABLE_RECORD_STATUS_NOMAL);
			eciVo.setTenantId(tenantId);
			eciVo.setUpdateAuthor(authorId);
			eciVo.setUpdateTime(updateTime);
			equipClassDao.saveAiEquipClassInfo(eciVo);
		}

		// 操作记录
		Map<String, Object> paramRecord = new HashMap<String, Object>();
		Calendar now = Calendar.getInstance();
		paramRecord.put("month", String.valueOf(now.get(Calendar.MONTH) + 1));
		paramRecord.put("day", String.valueOf(now.get(Calendar.DAY_OF_MONTH)));
		paramRecord.put("userId", "");
		paramRecord.put("queueId", "");
		paramRecord.put("opUser", authorId);
		paramRecord.put("opTime", updateTime);
		paramRecord.put("remark", oprInfo.get("opNote"));
		paramRecord.put("busiCategory", Constants.DOCTOR_ACTIVE_BUSI_TYPE_10);
		paramRecord.put("opUsertype", Constants.OPCODE_TYPE_DOCTOR);
		paramRecord.put("id", updateAccept);
		paramRecord.put("opDesc", oprInfo.get("opNote"));
		paramRecord.put("opCode", oprInfo.get("opCode"));
		paramRecord.put("busiId", null);
		paramRecord.put("tenantId", tenantId);
		paramRecord.put("opType", oprInfo.get("opType"));
		paramRecord.put("taskId", "");
		paramRecord.put("breifIntro", null);
		iaOperationRecordDao.saveOperationRecord(paramRecord);

		return outMap;
	}

	// 设置设备为无效或有效
	@Transactional
	public Map<String, Object> setEquipStatus(Map<String, Object> mapIn) throws Exception {
		Map<String, Object> argMap = new HashMap<String, Object>(mapIn);
		Map<String, Object> outMap = new HashMap<String, Object>();
		Map<String, Object> sessionInfo = ToolUtil.typeCast(argMap.get("sessionInfo"));
		Map<String, Object> oprInfo = ToolUtil.typeCast(argMap.get("oprInfo"));
		Map<String, Object> equipInfo = ToolUtil.typeCast(argMap.get("equipInfo"));
		String tenantId = (String) sessionInfo.get("tenantId");
		String authorId = (String) sessionInfo.get("authorId");
		String equipId = (String) equipInfo.get("equipId");
		String status = (String) equipInfo.get("status");
		String updateTime = (String) oprInfo.get("updateTime");
		String updateAccept = (String) oprInfo.get("updateAccept");

		// 修改设备状态
		Map<String, Object> upMapIn = new HashMap<String, Object>();
		upMapIn.put("id", equipId);
		upMapIn.put("updateTime", updateTime);
		upMapIn.put("updateAuthor", authorId);
		upMapIn.put("status", status);
		int iu = equipDao.updateAiEquip(upMapIn);
		if (0 == iu) {
			throw (new AppException(ErrorCode.IMG_EXCEPTION_EQUIP_NOT_EXISTS, "根据设备id未查询到对应设备信息，设置失败！"));
		}

		// 操作记录
		Map<String, Object> paramRecord = new HashMap<String, Object>();
		Calendar now = Calendar.getInstance();
		paramRecord.put("month", String.valueOf(now.get(Calendar.MONTH) + 1));
		paramRecord.put("day", String.valueOf(now.get(Calendar.DAY_OF_MONTH)));
		paramRecord.put("userId", "");
		paramRecord.put("queueId", "");
		paramRecord.put("opUser", authorId);
		paramRecord.put("opTime", updateTime);
		paramRecord.put("remark", oprInfo.get("opNote"));
		paramRecord.put("busiCategory", Constants.DOCTOR_ACTIVE_BUSI_TYPE_10);
		paramRecord.put("opUsertype", Constants.OPCODE_TYPE_DOCTOR);
		paramRecord.put("id", updateAccept);
		paramRecord.put("opDesc", oprInfo.get("opNote"));
		paramRecord.put("opCode", oprInfo.get("opCode"));
		paramRecord.put("busiId", null);
		paramRecord.put("tenantId", tenantId);
		paramRecord.put("opType", oprInfo.get("opType"));
		paramRecord.put("taskId", "");
		paramRecord.put("breifIntro", null);
		iaOperationRecordDao.saveOperationRecord(paramRecord);

		return outMap;
	}

	// 设备列表查询接口实现
	public Map<String, Object> listEquipInfo(Map<String, Object> mapIn) throws Exception {
		Jedis jedis = null;
		Map<String, Object> outMap = new HashMap<String, Object>();
		List<Map<String, Object>> equipList = new ArrayList<Map<String, Object>>();
		int total = equipDao.countEquipByCondition(mapIn);
		if (total > 0) {
			equipList = equipDao.listEquipMapByCondition(mapIn);
		}
		try {
			//用于判断是否程序的状态（正常，异常）
			jedis = pool.getResource();
			jedis.select(2);
			String strFlag = "";
			if(!CollectionUtils.isEmpty(equipList)) {
				for(int i=0;i<equipList.size();i++) {
					strFlag =  jedis.get((String)equipList.get(i).get("programId"));
					if(StringUtils.isBlank(strFlag)) {
						equipList.get(i).put("flag", false);
					}else {
						equipList.get(i).put("flag", true);
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (jedis != null) {
				jedis.close();
			}
		}
		outMap.put("rows", equipList);
		outMap.put("total", total);

		return outMap;
	}

	// 标记小程序的状态
	@Override
	public Map<String, Object> makeFlag(Map<String, Object> mapIn) throws Exception {
		Jedis jedis = null;
		Map<String,Object> map = new HashMap<String,Object>();
		try {
			String programId = (String) mapIn.get("programId");
			jedis = pool.getResource();
			jedis.select(2);
			jedis.set(programId, "true");
			jedis.expire(programId, 3600);
			map.put("surplusTime", jedis.ttl(programId));
			logger.info(programId+"剩余时间为："+jedis.ttl(programId)+"s");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (jedis != null) {
				jedis.close();
			}
		}
		return map;
	}
}
